<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>试卷管理系统</title>
    <link rel="stylesheet" href="static/index.css">
    <script src="static/vue@2.6.14.js"></script>
    <script src="static/index.js"></script>
    <script src="static/axios.min.js"></script>
    <style>
        /* Reset & Base styles */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            background: #f5f7fa;
            min-height: 100vh;
        }

        /* Layout & Container */
        #app {
            width: 100%;
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1400px;
            margin: 0 auto;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
            padding: 20px;
        }

        /* Tab Styles */
        .el-tabs__nav-wrap::after {
            height: 1px;
        }

        .el-tabs__item {
            font-size: 15px;
            padding: 0 25px;
        }

        /* Form Styles */
        .form-container {
            max-width: 800px;
            margin: 20px auto;
            padding: 30px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
        }

        /* Grid Layout for Papers */
        .exam-paper-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
            gap: 20px;
            margin: 20px 0;
        }

        .exam-paper-card {
            background: #fff;
            border-radius: 8px;
            padding: 20px;
            border: 1px solid #EBEEF5;
            transition: all 0.3s ease;
        }

        .exam-paper-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.15);
        }

        /* Paper Card Components */
        .exam-paper-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #EBEEF5;
        }

        .exam-paper-title {
            font-size: 16px;
            color: #303133;
            margin: 0;
            flex: 1;
        }

        .exam-paper-stats {
            display: flex;
            gap: 15px;
            margin: 15px 0;
            flex-wrap: wrap;
        }

        .exam-paper-stat-item {
            display: flex;
            align-items: center;
            gap: 5px;
            color: #606266;
            font-size: 14px;
        }

        .exam-paper-description {
            color: #606266;
            font-size: 14px;
            margin: 10px 0;
            padding: 10px;
            background: #f7f7f7;
            border-radius: 4px;
        }

        .exam-paper-footer {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            margin-top: 15px;
            padding-top: 15px;
            border-top: 1px dashed #EBEEF5;
        }

        /* Status Badge */
        .status-badge {
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 12px;
            margin-left: 8px;
        }

        .status-active {
            background: #e1f3d8;
            color: #67c23a;
        }

        .status-inactive {
            background: #fde2e2;
            color: #f56c6c;
        }

        /* Preview Dialog */
        .preview-dialog {
            min-width: 900px;
        }

        .preview-dialog .el-dialog__body {
            padding: 30px;
            max-height: 70vh;
            overflow-y: auto;
        }

        .preview-content {
            max-width: 900px;
            margin: 0 auto;
        }

        .paper-header {
            text-align: center;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 2px solid #EBEEF5;
        }

        .exam-info {
            display: flex;
            justify-content: center;
            gap: 20px;
            flex-wrap: wrap;
            margin-top: 15px;
        }

        .questions-list {
            margin-top: 30px;
        }

        .question-item {
            margin-bottom: 25px;
            padding: 20px;
            border: 1px solid #EBEEF5;
            border-radius: 8px;
            background: #fff;
        }

        .question-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .question-number {
            color: #409EFF;
            margin-right: 10px;
        }

        .options-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 15px;
            margin: 15px 0;
        }

        .option-item {
            padding: 10px;
            background: #f5f7fa;
            border-radius: 4px;
        }

        .correct-option {
            background: #f0f9eb;
            border: 1px solid #e1f3d8;
        }

        .correct-answer {
            margin-top: 15px;
            color: #67c23a;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 5px;
        }

        /* Question Pool */
        .question-pool {
            margin-top: 30px;
            padding: 20px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
        }

        /* Transfer Component */
        .el-transfer {
            display: flex;
            justify-content: center;
            align-items: flex-start;
            gap: 50px;
        }

        .el-transfer-panel {
            width: 350px !important;
        }

        .el-transfer__buttons {
            padding: 0 15px;
        }

        /* Responsive Adjustments */
        @media screen and (max-width: 768px) {
            .exam-paper-grid {
                grid-template-columns: 1fr;
            }

            .preview-dialog {
                width: 95% !important;
                min-width: unset;
            }

            .options-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
<div id="app">
    <div class="container">
        <el-tabs v-model="activeTab">
            <!-- 试卷管理 tab -->
            <el-tab-pane label="试卷管理" name="manage">
                <div class="toolbar">
                    <el-input
                            placeholder="搜索试卷名称"
                            v-model="searchKeyword"
                            style="width: 300px"
                            prefix-icon="el-icon-search"
                            @input="handleSearch"
                            clearable>
                    </el-input>
                </div>

                <div class="exam-paper-grid">
                    <div v-for="paper in papers" :key="paper.paperId" class="exam-paper-card">
                        <div class="exam-paper-header">
                            <h3 class="exam-paper-title">
                                {{paper.paperName}}
                                <span :class="['status-badge', paper.status === 1 ? 'status-active' : 'status-inactive']">
                                    {{paper.status === 1 ? '已启用' : '已禁用'}}
                                </span>
                            </h3>
                        </div>

                        <div class="exam-paper-stats">
                            <div class="exam-paper-stat-item">
                                <i class="el-icon-time"></i>
                                {{paper.duration}}分钟
                            </div>
                            <div class="exam-paper-stat-item">
                                <i class="el-icon-medal"></i>
                                总分：{{paper.totalScore}}分
                            </div>
                            <div class="exam-paper-stat-item" v-if="paper.passScore">
                                <i class="el-icon-success"></i>
                                及格分：{{paper.passScore}}分
                            </div>
                            <div class="exam-paper-stat-item">
                                <i class="el-icon-document"></i>
                                {{paper.questionList ? paper.questionList.length : 0}}题
                            </div>
                        </div>

                        <div class="exam-paper-description" v-if="paper.description">
                            <i class="el-icon-info"></i>
                            {{paper.description}}
                        </div>

                        <div class="exam-paper-stat-item">
                            <i class="el-icon-date"></i>
                            创建时间：{{formatTime(paper.createTime)}}
                        </div>

                        <div class="exam-paper-footer">
                            <el-button type="text" size="small" @click="viewPaper(paper)">
                                <i class="el-icon-view"></i> 预览
                            </el-button>
                            <el-button type="text" size="small" @click="editPaper(paper)">
                                <i class="el-icon-edit"></i> 编辑
                            </el-button>
                            <el-button
                                    type="text"
                                    size="small"
                                    @click="togglePaperStatus(paper)"
                                    :class="{'text-success': paper.status === 0, 'text-danger': paper.status === 1}">
                                <i :class="paper.status === 1 ? 'el-icon-close' : 'el-icon-check'"></i>
                                {{paper.status === 1 ? '禁用' : '启用'}}
                            </el-button>
                            <el-button type="text" size="small" @click="deletePaper(paper)">
                                <i class="el-icon-delete"></i> 删除
                            </el-button>
                        </div>
                    </div>
                </div>

                <div class="pagination-container" style="text-align: center; margin-top: 20px;">
                    <el-pagination
                            @size-change="handleSizeChange"
                            @current-change="handleCurrentChange"
                            :current-page="currentPage"
                            :page-sizes="[10, 20, 30, 50]"
                            :page-size="pageSize"
                            layout="total, sizes, prev, pager, next, jumper"
                            :total="total">
                    </el-pagination>
                </div>
            </el-tab-pane>

            <!-- 试卷组卷 tab -->
            <el-tab-pane label="试卷组卷" name="compose">
                <div class="form-container">
                    <el-form :model="currentPaper" ref="paperForm" label-width="100px" :rules="rules">
                        <el-form-item label="试卷名称" prop="paperName">
                            <el-input v-model="currentPaper.paperName" placeholder="请输入试卷名称"></el-input>
                        </el-form-item>

                        <el-form-item label="考试时长" prop="duration">
                            <el-input-number
                                    v-model="currentPaper.duration"
                                    :min="30"
                                    :max="180"
                                    :step="30"
                                    controls-position="right">
                            </el-input-number>
                            <span class="el-form-item__description">分钟</span>
                        </el-form-item>

                        <el-form-item label="及格分数" prop="passScore">
                            <el-input-number
                                    v-model="currentPaper.passScore"
                                    :min="0"
                                    :max="100"
                                    controls-position="right">
                            </el-input-number>
                        </el-form-item>

                        <el-form-item label="试卷说明" prop="description">
                            <el-input
                                    type="textarea"
                                    v-model="currentPaper.description"
                                    placeholder="请输入试卷说明"
                                    :rows="4">
                            </el-input>
                        </el-form-item>
                    </el-form>
                </div>

                <div class="question-pool">
                    <h3>选择题目</h3>
                    <div class="total-score" style="margin: 10px 0; color: #409EFF;">
                        当前已选择 {{selectedQuestions.length}} 题，总分：{{calculateTotalScore(selectedQuestions)}} 分
                    </div>
                    <el-transfer
                            v-model="selectedQuestions"
                            :data="allQuestions"
                            :titles="['题库', '已选题目']"
                            :button-texts="['移除', '添加']"
                            filterable>
                    </el-transfer>

                    <div style="text-align: center; margin-top: 20px;">
                        <el-button type="primary" @click="savePaper" :loading="loading">保存试卷</el-button>
                        <el-button @click="resetForm">重置</el-button>
                    </div>
                </div>
            </el-tab-pane>
        </el-tabs>

        <!-- 预览试卷对话框 -->
        <el-dialog
                title="试卷预览"
                :visible.sync="previewVisible"
                custom-class="preview-dialog"
                width="80%"
                :close-on-click-modal="false">
            <div v-if="previewPaper" class="preview-content">
                <div class="paper-header">
                    <h2>{{previewPaper.paperName}}</h2>
                    <div class="exam-info">
                        <el-tag size="medium">
                            <i class="el-icon-time"></i> 考试时长：{{previewPaper.duration}}分钟
                        </el-tag>
                        <el-tag size="medium" type="success">
                            <i class="el-icon-medal"></i> 总分：{{previewPaper.totalScore}}分
                        </el-tag>
                        <el-tag size="medium" type="warning" v-if="previewPaper.passScore">
                            <i class="el-icon-success"></i> 及格分：{{previewPaper.passScore}}分
                        </el-tag>
                        <el-tag size="medium" type="info">
                            <i class="el-icon-document"></i> 题目数：{{previewPaper.questionList.length}}
                        </el-tag>
                    </div>
                </div>

                <div v-if="previewPaper.description" class="exam-paper-description">
                    <h3><i class="el-icon-info"></i> 考试说明：</h3>
                    <p>{{previewPaper.description}}</p>
                </div>

                <div class="questions-list">
                    <div v-for="(question, index) in previewPaper.questionList"
                         :key="question.questionId"
                         class="question-item">
                        <div class="question-header">
                            <h4>
                                <span class="question-number">第{{index + 1}}题</span>
                                {{question.title}}
                            </h4>
                            <el-tag size="small" type="primary">{{question.score}}分</el-tag>
                        </div>

                        <div class="options-grid">
                            <div v-for="(option, key) in ['A', 'B', 'C', 'D']"
                                 :key="key"
                                 :class="['option-item', {'correct-option': question.correctAnswer === option}]">
                                <span class="option-label">{{option}}.</span>
                                {{question['option' + option]}}
                            </div>
                        </div>

                        <div class="correct-answer">
                            <i class="el-icon-success"></i>
                            正确答案：{{question.correctAnswer}}
                        </div>
                    </div>
                </div>
            </div>
            <span slot="footer">
                <el-button @click="previewVisible = false">关闭</el-button>
            </span>
        </el-dialog>
    </div>
</div>

<script>
    new Vue({
        el: '#app',
        data() {
            return {
                activeTab: 'manage',
                papers: [],
                currentPage: 1,
                pageSize: 10,
                total: 0,
                searchKeyword: '',
                previewVisible: false,
                loading: false,
                currentPaper: {
                    paperId: null,
                    paperName: '',
                    duration: 90,
                    passScore: 60,
                    description: '',
                    questions: [],
                    totalScore: 0,
                    status: 1
                },
                previewPaper: null,
                selectedQuestions: [],
                allQuestions: [],
                rules: {
                    paperName: [
                        {required: true, message: '请输入试卷名称', trigger: 'blur'},
                        {min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur'}
                    ],
                    duration: [
                        {required: true, message: '请设置考试时长', trigger: 'blur'},
                        {type: 'number', min: 30, max: 180, message: '考试时长必须在30-180分钟之间', trigger: 'blur'}
                    ],
                    passScore: [
                        {type: 'number', min: 0, max: 100, message: '及格分数必须在0-100分之间', trigger: 'blur'}
                    ]
                }
            }
        },
        methods: {
            formatTime(time) {
                if (!time) return '';
                const date = new Date(time);
                return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
            },

            calculateTotalScore(questionIds) {
                return this.allQuestions
                    .filter(q => questionIds.includes(q.key))
                    .reduce((total, q) => total + (Number(q.score) || 0), 0);
            },

            async loadPapers() {
                try {
                    this.loading = true;
                    const {data} = await axios.get('/paper', {
                        params: {
                            operation: 'findPage',
                            pageNum: this.currentPage,
                            pageSize: this.pageSize,
                            keyword: this.searchKeyword
                        }
                    });

                    if (data.code === 200) {
                        this.papers = data.data.list.map(paper => ({
                            ...paper,
                            questionList: paper.questionList || [],
                            questions: paper.questions ? JSON.parse(paper.questions) : []
                        }));
                        this.total = data.data.total;
                    }
                } catch (error) {
                    this.$message.error('获取试卷列表失败');
                } finally {
                    this.loading = false;
                }
            },

            async togglePaperStatus(paper) {
                try {
                    const newStatus = paper.status === 1 ? 0 : 1;
                    const {data} = await axios.post(`/paper?operation=update`, {
                        paperId: paper.paperId,
                        status: newStatus
                    });

                    if (data.code === 200) {
                        this.$message.success(`试卷已${newStatus == 1 ? '启用' : '禁用'}`);
                        paper.status = newStatus;
                    }
                } catch (error) {
                    this.$message.error('操作失败');
                }
            },

            handleSearch() {
                this.currentPage = 1;
                this.loadPapers();
            },

            handleSizeChange(val) {
                this.pageSize = val;
                this.currentPage = 1;
                this.loadPapers();
            },

            handleCurrentChange(val) {
                this.currentPage = val;
                this.loadPapers();
            },

            async loadQuestions() {
                try {
                    const {data} = await axios.get('/question?operation=findAll');
                    if (data.code === 200) {
                        this.allQuestions = data.data.map(q => ({
                            key: q.questionId.toString(),
                            label: `${q.title} (${q.score}分)`,
                            disabled: false,
                            ...q,
                            score: Number(q.score) || 0
                        }));
                    }
                } catch (error) {
                    this.$message.error('获取题库失败');
                }
            },

            async savePaper() {
                try {
                    await this.$refs.paperForm.validate();

                    if (!this.selectedQuestions.length) {
                        return this.$message.warning('请至少选择一道题目');
                    }

                    const totalScore = this.calculateTotalScore(this.selectedQuestions);
                    if (totalScore <= 0) {
                        return this.$message.warning('试卷总分必须大于0');
                    }

                    if (this.currentPaper.passScore > totalScore) {
                        return this.$message.warning('及格分不能大于总分');
                    }

                    const paperData = {
                        ...this.currentPaper,
                        questions: JSON.stringify(this.selectedQuestions),
                        questionCount: this.selectedQuestions.length,
                        totalScore,
                        updateTime: new Date().toISOString()
                    };

                    const operation = paperData.paperId ? 'update' : 'create';
                    const loading = this.$loading({
                        lock: true,
                        text: `正在${operation == 'create' ? '创建' : '更新'}试卷...`,
                        background: 'rgba(0, 0, 0, 0.7)'
                    });

                    const {data} = await axios.post(`/paper?operation=${operation}`, paperData);

                    if (data.code === 200) {
                        this.$message.success(`${operation == 'create' ? '创建' : '更新'}成功`);
                        this.activeTab = 'manage';
                        await this.loadPapers();
                        this.resetForm();
                    }
                    loading.close();
                } catch (error) {
                    this.$message.error('保存失败');
                }
            },

            async viewPaper(paper) {
                try {
                    const questionIds = Array.isArray(paper.questions) ?
                        paper.questions :
                        JSON.parse(paper.questions || '[]');

                    const questions = questionIds
                        .map(qId => {
                            const question = this.allQuestions.find(q => q.key === qId.toString());
                            return question ? {
                                questionId: qId,
                                ...question
                            } : null;
                        })
                        .filter(Boolean);

                    this.previewPaper = {
                        ...paper,
                        questionList: questions,
                        paperName: paper.paperName
                    };
                    this.previewVisible = true;
                } catch (error) {
                    this.$message.error('预览失败');
                }
            },

            editPaper(paper) {
                try {
                    const questions = Array.isArray(paper.questions) ?
                        paper.questions :
                        JSON.parse(paper.questions || '[]');

                    this.currentPaper = {
                        paperId: paper.paperId,
                        paperName: paper.paperName,
                        duration: Number(paper.duration),
                        passScore: Number(paper.passScore) || 60,
                        description: paper.description || '',
                        questions,
                        totalScore: Number(paper.totalScore) || 0,
                        status: paper.status
                    };

                    this.selectedQuestions = questions.map(String);
                    this.activeTab = 'compose';

                    this.$nextTick(() => this.$refs.paperForm?.clearValidate());
                } catch (error) {
                    this.$message.error('编辑试卷失败');
                }
            },

            deletePaper(paper) {
                this.$confirm('确认删除该试卷吗？删除后不可恢复', '提示', {
                    type: 'warning'
                }).then(async () => {
                    try {
                        const {data} = await axios.post(`/paper?operation=delete&paperId=${paper.paperId}`);
                        if (data.code === 200) {
                            this.$message.success('删除成功');
                            await this.loadPapers();
                        }
                    } catch (error) {
                        this.$message.error('删除失败');
                    }
                });
            },

            resetForm() {
                this.currentPaper = {
                    paperId: null,
                    paperName: '',
                    duration: 90,
                    passScore: 60,
                    description: '',
                    questions: [],
                    totalScore: 0,
                    status: 1
                };
                this.selectedQuestions = [];
                this.$refs.paperForm?.resetFields();
            }
        },
        created() {
            this.loadQuestions().then(() => this.loadPapers());
        }
    });
</script>
</body>
</html>